import {
  defineComponent,
  onMounted,
  ref,
  Ref,
  resolveComponent,
  watch,
  h,
} from 'vue';
import {
  getDataPickerProps,
  getEditorEmits,
  useFocusAndBlur,
  useNamespace,
} from '@ibiz-template/vue3-util';
import './ibiz-picker-select-view.scss';
import { clone } from 'ramda';
import { EventBase } from '@ibiz-template/runtime';
import { PickerEditorController } from '../picker-editor.controller';

export const IBizPickerSelectView = defineComponent({
  name: 'IBizPickerSelectView',
  props: getDataPickerProps<PickerEditorController>(),
  emits: getEditorEmits(),
  setup(props, { emit }) {
    const ns = useNamespace('picker-select-view');

    const c = props.controller!;

    const editorModel = c.model;

    // 是否单选
    const singleSelect = ref(true);
    if (editorModel.editorParams) {
      if (editorModel.editorParams.multiple) {
        singleSelect.value = !c.toBoolean(editorModel.editorParams.multiple);
      }
    }

    // 当前多选框选中值的key集合
    const keySet: Ref<string[]> = ref([]);

    // 所有操作过的下拉选项对象集合
    const items: Ref<IData[]> = ref([]);

    // 选中数据
    let selectedData = [];

    // 输入框值(搜索值)
    const queryValue: Ref<string> = ref('');

    // 下拉显示控制变量
    const visible = ref(false);

    // 选择视图宽度
    const pickViewWidth = ref('auto');

    // 视图上下文
    const context = ref(clone(c.context));

    // 视图参数
    const params = ref(clone(c.params));

    // 输入框change事件
    const onInputChange = () => {
      context.value = { query: queryValue.value, ...context.value };
    };

    // 改变显示事件
    const triggerMenu = (show?: boolean) => {
      if (props.disabled) {
        return;
      }
      if (!show) {
        visible.value = !visible.value;
      } else {
        visible.value = show;
      }
    };

    // 聚焦失焦事件
    const { componentRef: editorRef } = useFocusAndBlur(
      () => emit('focus'),
      () => emit('blur'),
    );

    watch(
      () => props.value,
      newVal => {
        if (singleSelect.value) {
          queryValue.value = newVal || '';
          if (!props.data || !c.valueItem || !props.data[c.valueItem]) {
            ibiz.log.error('值项异常');
          } else {
            selectedData = [
              { srfkey: props.data[c.valueItem], srfmajortext: props.value },
            ];
            params.value.selectedData = selectedData;
          }
        } else {
          keySet.value = [];
          const selectItems: IData[] = [];
          if (newVal) {
            if (!props.data || !c.valueItem || !props.data[c.valueItem]) {
              ibiz.log.error('值项异常');
            } else {
              const tempValue = props.data[c.valueItem].split(',');
              const tempText = newVal.split(',');
              tempValue.forEach((srfkey: string, index: number) => {
                selectItems.push({
                  srfmajortext: tempText[index],
                  srfkey,
                });
              });
              items.value = [];
              selectItems.forEach((item: IData) => {
                keySet.value.push(item.srfkey);
                const index = items.value.findIndex(i =>
                  Object.is(i.srfkey, item.srfkey),
                );
                if (index < 0) {
                  items.value.push({
                    srfmajortext: item.srfmajortext,
                    srfkey: item.srfkey,
                  });
                }
              });
            }
          }
          selectedData = selectItems;
          params.value.selectedData = selectedData;
        }
      },
      {
        immediate: false,
        deep: true,
      },
    );

    onMounted(() => {
      if (editorRef.value) {
        pickViewWidth.value = `${editorRef.value.offsetWidth}px`;
      }
    });

    // 清除
    const onClear = () => {
      // 清空回填数据
      const dataItems = c.dataItems;
      if (dataItems?.length) {
        dataItems.forEach(dataItem => {
          emit('change', null, dataItem.id);
        });
      }
      if (c.valueItem) {
        emit('change', null, c.valueItem);
      }
      emit('change', null);
    };

    // 视图数据改变
    const onViewDataChange = (event: IData[]) => {
      if (event.length === 0) {
        onClear();
        return;
      }
      if (singleSelect.value) {
        visible.value = false;
        if (c.valueItem) {
          const tempValue = event[0][c.keyName]
            ? event[0][c.keyName]
            : event[0].srfkey;
          emit('change', tempValue, c.valueItem);
        }
        const tempText = event[0][c.textName]
          ? event[0][c.textName]
          : event[0].srfmajortext;
        emit('change', tempText);
      } else {
        let tempValue: string = '';
        let tempText: string = '';
        if (event && Array.isArray(event)) {
          items.value = [];
          event.forEach((select: IData) => {
            const srfkey = select[c.keyName]
              ? select[c.keyName]
              : select.srfkey;
            tempValue += `${srfkey},`;
            const srfmajortext = select[c.textName]
              ? select[c.textName]
              : select.srfmajortext;
            tempText += `${srfmajortext},`;
            const index = items.value.findIndex(item =>
              Object.is(item.srfkey, srfkey),
            );
            if (index < 0) {
              items.value.push({ srfmajortext, srfkey });
            }
          });
        }
        tempValue = tempValue.substring(0, tempValue.length - 1);
        tempText = tempText.substring(0, tempText.length - 1);
        if (c.valueItem) {
          emit('change', tempValue, c.valueItem);
        }
        emit('change', tempText);
      }
    };

    // 打开数据链接视图
    const openLinkView = async (e: MouseEvent) => {
      e.stopPropagation();
      const res = await c.openLinkView(props.data);
      if (res) {
        onViewDataChange(res);
      }
    };

    // 下拉选中回调
    const onSelectChange = (selects: string[]) => {
      const val: IData[] = [];
      if (selects.length > 0) {
        selects.forEach((select: string) => {
          const index = items.value.findIndex(item =>
            Object.is(item.srfkey, select),
          );
          if (index >= 0) {
            val.push(items.value[index]);
          }
        });
      }
      let tempValue: string = '';
      let tempText: string = '';
      val.forEach((select: IData) => {
        const srfkey = select[c.keyName] ? select[c.keyName] : select.srfkey;
        tempValue += `${srfkey},`;
        const srfmajortext = select[c.textName]
          ? select[c.textName]
          : select.srfmajortext;
        tempText += `${srfmajortext},`;
      });
      tempValue = tempValue.substring(0, tempValue.length - 1);
      tempText = tempText.substring(0, tempText.length - 1);
      // 处理值项和本身的值
      if (c.valueItem) {
        emit('change', tempValue, c.valueItem);
      }
      emit('change', tempText);
    };

    // 远程搜索
    const remoteMethod = (e: string) => {
      queryValue.value = e;
    };

    // 绑定事件
    const onSelectionChange = (event: EventBase) => {
      onViewDataChange(event.data);
    };

    return {
      ns,
      c,
      singleSelect,
      keySet,
      items,
      queryValue,
      visible,
      pickViewWidth,
      context,
      params,
      editorRef,
      onInputChange,
      triggerMenu,
      onViewDataChange,
      onClear,
      openLinkView,
      onSelectChange,
      remoteMethod,
      onSelectionChange,
    };
  },
  render() {
    return (
      <div class={[this.ns.b()]} ref='editorRef'>
        <el-dropdown trigger='click' popper-class={this.ns.b('popper')}>
          {{
            default: () => {
              return this.singleSelect ? (
                <el-input
                  v-model={this.queryValue}
                  class={this.ns.b('input')}
                  placeholder={this.c.placeHolder}
                  disabled={this.disabled}
                  readonly={this.readonly}
                  onChange={this.onInputChange}
                  onFocus={() => {
                    this.triggerMenu(true);
                  }}
                >
                  {{
                    suffix: () => {
                      return [
                        this.queryValue && !this.disabled && !this.readonly && (
                          <ion-icon
                            onClick={this.onClear}
                            name='clear'
                          ></ion-icon>
                        ),
                        this.c.model.linkAppViewId && (
                          <ion-icon
                            onClick={this.openLinkView}
                            name='link-arrow'
                          ></ion-icon>
                        ),
                      ];
                    },
                  }}
                </el-input>
              ) : (
                <el-select
                  popper-class='select'
                  model-value={this.keySet}
                  placeholder={this.c.placeHolder ? this.c.placeHolder : ' '}
                  multiple
                  filterable
                  remote
                  remote-method={this.remoteMethod}
                  onChange={this.onSelectChange}
                  onFocus={() => {
                    this.triggerMenu(true);
                  }}
                  disabled={this.disabled || this.readonly}
                >
                  {this.items.map((item: IData, index: number) => {
                    return (
                      <el-option
                        key={item.srfkey + index}
                        label={item.srfmajortext}
                        value={item.srfkey}
                      ></el-option>
                    );
                  })}
                </el-select>
              );
            },
            dropdown: () => {
              const viewShell = resolveComponent('IBizViewShell');
              return (
                <el-dropdown-menu>
                  {this.c.pickupView &&
                    h(viewShell, {
                      context: this.context,
                      params: this.params,
                      viewId: this.c.pickupView.id,
                      style: { height: '100%', width: this.pickViewWidth },
                      onSelectionChange: this.onSelectionChange,
                    })}
                </el-dropdown-menu>
              );
            },
          }}
        </el-dropdown>
      </div>
    );
  },
});
